package org.yxing.palpalgps.activity;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import org.yxing.palpalgps.AbstractActivity;
import org.yxing.palpalgps.R;
import org.yxing.palpalgps.domain.AsyncImageLoader;
import org.yxing.palpalgps.domain.UserInfo;
import org.yxing.palpalgps.http.AsyncRequest;
import org.yxing.palpalgps.http.AsyncRequest.FetchListener;
import org.yxing.palpalgps.oauth.OAuth;
import org.yxing.palpalgps.utils.ConfigHelper;
import org.yxing.palpalgps.utils.Helper;
import org.yxing.palpalgps.utils.Utils;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.DatePicker;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class ProfileEditActivity extends AbstractActivity implements OnClickListener{
    
    private static final String TAG = ProfileEditActivity.class.getSimpleName();
    
    private static final int FACE_CAMERA_RESULT = 1;
    private static final int FACE_ALBUM_RESULT = 2;
    private static final int EDIT_NAME = 3;
    private static final int EDIT_GENDER = 4;
    private static final int EDIT_BIRTHDAY = 5;
    private static final int EDIT_RELATION = 6;
    private static final int EDIT_INTEREST = 7;
    private static final int FACE_CROP = 8;
    private UserInfo user;
    private RelativeLayout faceView;
    private TableRow rowName;
    private TableRow rowGender;
    private TableRow rowBirthday;
    private TableRow rowRelation;
    
    private ImageView faceImage;
    private TextView nameView;
    private TextView genderView;
    private TextView birthdayView;
    private TextView relationView;
    
    private File sdcardTempfile;
    private boolean hasSDCard;
    private File portrait = null;
    
    private int[] relationNames = {R.string.relation_0,
            R.string.relation_1,
            R.string.relation_2,
            R.string.relation_3,
            R.string.relation_4,
            R.string.relation_5,
            R.string.relation_6,
            R.string.relation_7,
            R.string.relation_8
        };

    File sdcardTempDir;
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.profile_edit);
        setTitle(getString(R.string.profile_edit));
        
        user = ConfigHelper.nowUser;
        faceView      = (RelativeLayout) findViewById(R.id.faceView);
        rowName       = (TableRow) findViewById(R.id.rowName);
        rowGender     = (TableRow) findViewById(R.id.rowGender);
        rowBirthday   = (TableRow) findViewById(R.id.rowBirthday);
        rowRelation   = (TableRow) findViewById(R.id.rowRelation);
        
        faceImage     = (ImageView) findViewById(R.id.faceImage);
        nameView      = (TextView) findViewById(R.id.name);
        genderView    = (TextView) findViewById(R.id.gender);
        birthdayView  = (TextView) findViewById(R.id.birthday);
        relationView  = (TextView) findViewById(R.id.relation);
        
        faceView.setOnClickListener(new FaceViewClickListener());
        rowName.setOnClickListener(this);
        rowGender.setOnClickListener(this);
        rowBirthday.setOnClickListener(this);
        rowRelation.setOnClickListener(this);
        
        hasSDCard = Utils.hasSDCard();
        if (hasSDCard) {
            sdcardTempDir = new File(Environment.getExternalStorageDirectory() + File.separator + "tmp");
            if (!sdcardTempDir.exists())
                sdcardTempDir.mkdirs();
            portrait = new File(ConfigHelper.getPortraitPath(), "portrait.jpg");
        }
        
        showProfile();
    }
    
    
    /**
     * 获取用户个人信息
     */
    private void showProfile() {
        nameView.setText(user.getName());
        birthdayView.setText(user.getBirthday());
        displayGender();
        diaplayFace();
        diaplayRelation();
    }
    
    /**
     * 修改头像
     * @author yuxing
     *
     */
    private class FaceViewClickListener implements View.OnClickListener {
        public void onClick(View v) {
            
            
            if (!hasSDCard) {
                displayToast(getString(R.string.no_found_sdcard));
                return;
            }
            
            String[] items = new String[]{getString(R.string.camera_piciture), getString(R.string.album_piciture)};
            AlertDialog.Builder builder = new AlertDialog.Builder(ProfileEditActivity.this)
                .setTitle(getString(R.string.select_face_image))
                .setItems(items, new DialogInterface.OnClickListener() {
                    
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent;
                        switch(which) {
                        case 0:
                            sdcardTempfile = new File(sdcardTempDir, System.currentTimeMillis() + ".jpg");
                            intent = new Intent();
                            intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
                            Uri uri = Uri.fromFile(sdcardTempfile);
                            intent.putExtra("output", uri);
                            startActivityForResult(intent, FACE_CAMERA_RESULT);
                            break;
                        case 1:
                            intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
                            startActivityForResult(intent, FACE_ALBUM_RESULT);
                            break;
                        }
                    }
                });
            builder.show();
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
            case FACE_CAMERA_RESULT:
                try {
                    cropImage(Uri.fromFile(sdcardTempfile));
                } catch (FileNotFoundException e) {
                    Log.w(TAG, e.getMessage());
                } catch (Exception e) {
                    Log.w(TAG, e.getMessage());
                }

                break;
            case FACE_ALBUM_RESULT:
                try {
                    cropImage(data.getData());
                } catch (FileNotFoundException e) {
                    Log.w(TAG, e.getMessage());
                } catch (Exception e) {
                    Log.w(TAG, e.getMessage());
                }
                break;
            case EDIT_NAME:
                String content = data.getStringExtra("edit_text");
                user.setName(content);
                nameView.setText(user.getName());
                //update
                uploadInfo(UserInfo.KEY_NAME, user.getName(), EDIT_NAME);
                break;
            case FACE_CROP:
                uploadFace();
                break;
            }
        }
    }
    
    private void displayGender() {
        genderView.setText((user.getGender().equals("m")) ? getString(R.string.male) : getString(R.string.female));
    }
    
    private void diaplayFace() {
        if (user.getFace() != null && user.getFace().length() > 0) {
            AsyncImageLoader imageLoader = new AsyncImageLoader();
            String imageUrl = Helper.getSmallPictureUrl(user.getFace());
            imageLoader.loadDrawable(imageUrl, faceImage, new faceViewCallBack());
        }
    }
    
    private void diaplayRelation() {
        String str = getString(relationNames[user.getRelation()]);
        relationView.setText(str);
    }
    
    private class faceViewCallBack implements AsyncImageLoader.ImageCallback {

        public void imageLoaded(Drawable imageDrawable, ImageView imageView, String imageUrl) {
            imageView.setImageDrawable(imageDrawable);
        }
        
    }
    
    public void onClick(View v) {
        
        switch (v.getId()) {
        case R.id.rowName:
            editText(user.getName(), R.string.edit_name, EDIT_NAME);
            break;
        case R.id.rowGender:
            genderDialog();
            break;
        case R.id.rowBirthday:
            birthdayDialog();
            break;
        case R.id.rowRelation:
            relationDialog();
            break;
        }
    }
    
    private void editText(String text, int title, int requestCode) {
        Intent intent = new Intent(this, MEditText.class);
        intent.putExtra("edit_text", text);
        intent.putExtra("title", title);
        startActivityForResult(intent, requestCode);
    }
    
    /**
     * 更新个人信息
     * @param key
     * @param value
     * @param what
     */
    private void uploadInfo(final String key, final String value, final int what) {
        AsyncRequest ar = new AsyncRequest(this);
        List<BasicNameValuePair> params = OAuth.createAuthParams();
        params.add(new BasicNameValuePair(key, value));
        ar.fetch("profile/update", params, new FetchListener() {
            
            public void onError(int code, String msg) {
                displayToast(msg);
            }
            
            public void onComplete(JSONObject response) {
                displayToast(getString(R.string.update_success));
            }
        });
    }
    
    /**
     * a dialog for gender select
     */
    private void genderDialog() {
        String[] items = {getString(R.string.male), getString(R.string.female)};
        int which = (user.getGender().equals("m")) ? 0 : 1;
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
        alertDialog.setSingleChoiceItems(items, which, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                String gender = (which == 0) ? "m" : "f";
                user.setGender(gender);
                displayGender();    //display gender to TextView
                dialog.cancel();
                uploadInfo(UserInfo.KEY_GENDER, gender, EDIT_GENDER);   //upload data to server
            }
        });
        alertDialog.setNegativeButton(getString(R.string.cancel), null);
        alertDialog.show();
    }
    
   /**
     * a dialog for birthday
     */
    private void birthdayDialog() {
        final Calendar c = Utils.getDate(user.getBirthday());
        DatePickerDialog dialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
            
            public void onDateSet(DatePicker view, int year, int monthOfYear,
                    int dayOfMonth) {
                SimpleDateFormat format = Helper.getSimpleDateFormat();
                c.set(year, monthOfYear, dayOfMonth);
//                Log.v(TAG, "change to " + format.format(c.getTime()));
                String birthday = format.format(c.getTime());
                birthdayView.setText(birthday);
                user.setBirthday(birthday);
                uploadInfo(UserInfo.KEY_BIRTHDAY, birthday, EDIT_BIRTHDAY);
                
            }
        }, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
        dialog.show();
    }
    
    /**
     * a dialog for relation
     */
    private void relationDialog() {
        String[] items = new String[9];
        for (int i = 0; i <= 8; i++) 
            items[i] = getString(relationNames[i]);
        
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setSingleChoiceItems(items, user.getRelation(), new DialogInterface.OnClickListener() {
            
            public void onClick(DialogInterface dialog, int which) {
                user.setRelation(which);
                uploadInfo(UserInfo.KEY_RELATION, Integer.toString(which), EDIT_RELATION);
                diaplayRelation();
                dialog.cancel();
            }
        });
        builder.setNegativeButton(getString(R.string.cancel), null);
        builder.show();
    }
    
    /**
     * 剪切图片
     * @param uri
     * @throws IOException
     */
    private void cropImage(Uri uri) throws IOException {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*"); 
        intent.putExtra("crop", "true"); 
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", Helper.PICTURE_SIZE_BIG);
        intent.putExtra("outputY", Helper.PICTURE_SIZE_BIG);
        intent.putExtra("noFaceDetection", true);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(portrait));
        startActivityForResult(intent, FACE_CROP);
    }
    
    /**
     * 上传头像
     * @param is
     */
    public void uploadFace() {
        pd.cancel();
        pd.show();
        new Thread(){
            public void run(){
                String url = Helper.getAppUrl("photo/upload");
                OAuth auth = new OAuth();
                List<BasicNameValuePair> params = OAuth.createAuthParams();
                InputStream upis = null;
                String result;
                try {
                    upis = new FileInputStream(portrait);
                    result = Utils.uploadFile(url, upis, portrait.getName(), "photo", params);
                    if (result != null)
                        Log.v(TAG, result);
                    uploadFaceHandler.sendMessage(uploadFaceHandler.obtainMessage(0, result));
                    upis.close();
                } catch (IOException e) {
                    Log.w(TAG, "上传头像失败" + e.getMessage());
                } finally {
                    pd.cancel();
                    
                    //crear sdcard temp image file
                    if (sdcardTempfile != null && sdcardTempfile.exists())
                        sdcardTempfile.delete();
                }
            }
        }.start();
    }
    
    /**
     * 上传头像完成
     */
    private Handler uploadFaceHandler = new Handler(){
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case 0:
                try {
                    JSONObject json = new JSONObject((String)msg.obj);
                    if (json.getInt("error_code") == 0) {
                        String pid = json.getString("pid"); //图片id
                        user.setFace(pid);
                        setFace(user.getFace());
                    }
                } catch (JSONException e) {
                    Log.w(TAG, e.getMessage());
                }
                break;
            }
        }
    };
    
    /**
     * upload face
     * @param pid
     */
    private void setFace(final String pid) {
        AsyncRequest ar = new AsyncRequest(this);
        List<BasicNameValuePair> params = OAuth.createAuthParams();
        params.add(new BasicNameValuePair("pid", pid));
        ar.fetch("photo/avatar", params, new FetchListener() {
            
            public void onError(int code, String msg) {
                
            }
            
            public void onComplete(JSONObject response) {
                displayToast(getString(R.string.update_success));
                diaplayFace();
            }
        });
    }
}
